/****************************************************************************/    
/* NAME:           oscillator.c                                             */    
/* PURPOSE:        Manage all oscillator                                    */    
/* CREATED_BY:     Vyx                                                      */    
/* CREATION_DATE:  07/07/2012                                               */ 
/************************************** (C) Copyright 2012 AquaLink *********/

#include "oscillator.h"
#include "Hal_PwmManagement.h"
#include "tools.h"

#define Osci_TASK_DELAY    (10000)
#define Osci_NB_OSCILLATOR     (2)

/* List of oscillator definition */
Oscillator_def_t oscillateur_liste[Osci_NB_OSCILLATOR] = 
{
    {0, 30, 120, 50, FALSE, 1000, 0},
    {1, 30, 120, 50, FALSE, 1000, 0}
};

/**    
  * @brief  Main function of oscillator.   
  * @param  none    
  * @retval None    
  */
void vTaskCTRL_OSCILLATOR()
{
    portTickType     xLastWakeTime;
    Oscillator_def_t oscillateur_x;
    char             mes[32]; 
    
    /* init */
    xLastWakeTime = xTaskGetTickCount();

    Oscillator_init();
    
    //xTaskCreate( (void*)vTask_OSCILLATOR_1, (void*)"osci1", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR_1 );
    xTaskCreate( (void*)vTask_OSCILLATOR_2, (void*)"osci2", configMINIMAL_STACK_SIZE+128, NULL, tskIDLE_PRIORITY+5, &xHandle_Task_OSCILLATOR_2 );

    /* Use to update the oscillator configration */
    while(1)
    {
        if ( uxQueueMessagesWaiting( oscillateur_queue ) > 0 )
        {
            xQueueReceive( oscillateur_queue, &oscillateur_x, 10); 
            
            oscillateur_liste[oscillateur_x.id].osci_x_min     = oscillateur_x.osci_x_min;
            oscillateur_liste[oscillateur_x.id].osci_x_max     = oscillateur_x.osci_x_max;
            oscillateur_liste[oscillateur_x.id].osci_x_speed   = oscillateur_x.osci_x_speed;
            oscillateur_liste[oscillateur_x.id].osci_x_linear  = oscillateur_x.osci_x_linear;
            oscillateur_liste[oscillateur_x.id].osci_x_pause   = oscillateur_x.osci_x_pause;
            oscillateur_liste[oscillateur_x.id].osci_x_mode    = oscillateur_x.osci_x_mode;
        
            sprintf(mes, "màj oscillateur %d", oscillateur_x.id+1);
            send_message(OSCILLATOR_1_MODULE_ID, normal, mes);
        }
        wait(Osci_TASK_DELAY);
    }
}

/**    
  * @brief  Manage oscillator 1.   
  * @param  none    
  * @retval None    
  */  
void vTask_OSCILLATOR_1()
{
    portTickType xLastWakeTime;
    uint16_t     LastPosition;
    uint16_t     PositionSetPoint;
    uint16_t     CurentPosition;
    bool         RotationDirection;
    
    /* init */
    xLastWakeTime     = xTaskGetTickCount();
    PositionSetPoint  = oscillateur_liste[0].osci_x_min;
    RotationDirection = FALSE;
    LastPosition      = 75;
    CurentPosition    = 75;
    
    while(1)
    {
      /* normal mode of actuator */
      if (oscillateur_liste[0].osci_x_mode == OSCI_NORMAL_MODE)
      {  
          /* Linear mode */
          if (oscillateur_liste[0].osci_x_linear == TRUE) 
          {
              if ( RotationDirection == FALSE ) 
              {
                  while(CurentPosition != oscillateur_liste[0].osci_x_max)
                  {    
                      PWM_SetPwmValue(OSCILLATOR_1, CurentPosition++);
                      wait(oscillateur_liste[0].osci_x_speed);
                  }
                  RotationDirection = TRUE;
              }
              else  
              {
                  while(CurentPosition != oscillateur_liste[0].osci_x_min )
                  {
                      PWM_SetPwmValue(OSCILLATOR_1, CurentPosition--);
                      wait(oscillateur_liste[0].osci_x_speed);
                  }
                  RotationDirection = FALSE;
              }
          }
          /* Random mode */
          else 
          {
              PositionSetPoint = TOOL_rand_min_max(oscillateur_liste[0].osci_x_min, 
                                                   oscillateur_liste[0].osci_x_max);
          
              if ( PositionSetPoint > LastPosition )
              {
                  while(CurentPosition != PositionSetPoint)
                  {
                      PWM_SetPwmValue(OSCILLATOR_1, CurentPosition++);
                      wait(oscillateur_liste[0].osci_x_speed);
                  }
              }
              else
              {
                  while(CurentPosition != PositionSetPoint)
                  {
                      PWM_SetPwmValue(OSCILLATOR_1, CurentPosition--);
                      wait(oscillateur_liste[0].osci_x_speed);
                  }
              }
          
              LastPosition = PositionSetPoint;
              wait(oscillateur_liste[0].osci_x_pause);
          }
      }
      /* test mode, check min and max position */
      else
      {
        /* test min position */
        /* get value from screen */
        /* PWM_SetPwmValue(OSCILLATOR_1, TestedValueFromScreen); */
        
        /* if (TestedValueFromScreen is needed)*/
        /* oscillateur_liste[0].osci_x_min = TestedValueFromScreen */
        
        /*test max position */
        /* get value from screen */
        /* PWM_SetPwmValue(OSCILLATOR_1, TestedValueFromScreen); */
        
        /* if (TestedValueFromScreen is needed)*/
        /* oscillateur_liste[0].osci_x_max = TestedValueFromScreen */
      } 
    }
}

/**    
  * @brief  Manage oscillator 2.   
  * @param  none    
  * @retval None    
  */  
void vTask_OSCILLATOR_2()
{
    portTickType xLastWakeTime;
    uint16_t     LastPosition;
    uint16_t     PositionSetPoint;
    uint16_t     CurentPosition;
    bool         RotationDirection;
    
    /* init */
    xLastWakeTime     = xTaskGetTickCount();
    PositionSetPoint  = oscillateur_liste[1].osci_x_min;
    RotationDirection = FALSE;
    LastPosition      = 75;
    CurentPosition    = 75;
    
    while(1)
    {
        /* Linear mode */
        if (oscillateur_liste[1].osci_x_linear == TRUE) 
        {
            if ( RotationDirection == FALSE ) 
            {
                while(CurentPosition != oscillateur_liste[1].osci_x_max)
                {    
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition++);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
                RotationDirection = TRUE;
            }
            else  
            {
                while(CurentPosition != oscillateur_liste[1].osci_x_min )
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition--);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
                RotationDirection = FALSE;
            }
        }
        /* Random mode */
        else 
        {
            PositionSetPoint = TOOL_rand_min_max(oscillateur_liste[1].osci_x_min, 
                                            oscillateur_liste[1].osci_x_max);
        
            if ( PositionSetPoint > LastPosition )
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition++);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
            }
            else
            {
                while(CurentPosition != PositionSetPoint)
                {
                    PWM_SetPwmValue(OSCILLATOR_2, CurentPosition--);
                    wait(oscillateur_liste[1].osci_x_speed);
                }
            }
        
            LastPosition = PositionSetPoint;
            wait(oscillateur_liste[1].osci_x_pause);
        }
    }
}

/**    
  * @brief  Initialisation of modules.
  * @param  none
  * @retval None
  */  
void Oscillator_init()
{

}